package com.domain.utils.alipay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.domain.common.AppLogger;
import com.domain.controller.LoginController;
import com.domain.utils.NotNullUtils;
import com.domain.utils.UUIDUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

public class AlipayUtil {
    /**
     * 日志
     */
    private static Logger logger = AppLogger.getLogger(LoginController.class.getSimpleName(), Level.INFO.toString(), true);

    /**
     * 支付创建订单信息
     *
     * @param body         对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。
     * @param subject      商品的标题/交易标题/订单标题/订单关键字等。
     * @param total_amount 总金额
     * @return
     */
    public static AlipayTradeAppPayResponse creatAlipayOrder(String body, String subject, String total_amount) throws AlipayApiException {
        //实例化客户端 String serverUrl, String appId, String privateKey, String format, String charset, String alipayPublicKey, String signType
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALI_APIURL, AlipayConfig.ALI_APPID, AlipayConfig.ALI_APP_PRIVATE_KEY, AlipayConfig.ALI_FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALI_ALIPAY_PUBLIC_KEY, AlipayConfig.ALI_SIGN_TYPE);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。
        model.setBody(body);
        //商品的标题/交易标题/订单标题/订单关键字等。
        model.setSubject(subject);
        //订单号
        model.setOutTradeNo(UUIDUtils.getRandomUUID());
        //总金额
        model.setTotalAmount(total_amount);
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.ALI_NOTIFYURL);
        //这里和普通的接口调用不同，使用的是sdkExecute
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        logger.info("支付返回的信息" + response);
        return response;
    }

    /**
     * 交易退款
     *
     * @param orderNum    商户订单号
     * @param returnMoney 退款的钱数
     * @param returnDesc  退款描述
     * @return
     * @throws AlipayApiException
     */
    public static AlipayTradeRefundResponse aliPayReturn(String orderNum, String returnMoney, String returnDesc) throws AlipayApiException {
        //实例化客户端 String serverUrl, String appId, String privateKey, String format, String charset, String alipayPublicKey, String signType
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALI_APIURL, AlipayConfig.ALI_APPID, AlipayConfig.ALI_APP_PRIVATE_KEY, AlipayConfig.ALI_FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALI_ALIPAY_PUBLIC_KEY, AlipayConfig.ALI_SIGN_TYPE);
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(orderNum); //与预授权转支付商户订单号相同，代表对该笔交易退款
        model.setRefundAmount(returnMoney);
        model.setRefundReason(returnDesc);
        model.setOutRequestNo("");//标识一次退款请求，同一笔交易多次退款需要保证唯一，如部分退款则此参数必传。
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizModel(model);
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        logger.info("response: {}" + response.getBody());
        return response;
    }


    /**
     * 获取AccessToken
     *
     * @param
     * @return
     */
    public static String buildRequest(String code) throws AlipayApiException {
        //实例化客户端 String serverUrl, String appId, String privateKey, String format, String charset, String alipayPublicKey, String signType
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALI_APIURL, AlipayConfig.ALI_APPID, AlipayConfig.ALI_APP_PRIVATE_KEY, AlipayConfig.ALI_FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALI_ALIPAY_PUBLIC_KEY, AlipayConfig.ALI_SIGN_TYPE);
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();//创建API对应的request类
        request.setGrantType("authorization_code");
        request.setCode(code);
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);//通过alipayClient调用API，获得对应的response类
        return response.getAccessToken();
    }

    /**
     * 获取用户信息
     *
     * @param accessToken
     * @return
     */
    public static AlipayUserInfoShareResponse get(String accessToken) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALI_APIURL, AlipayConfig.ALI_APPID, AlipayConfig.ALI_APP_PRIVATE_KEY, AlipayConfig.ALI_FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALI_ALIPAY_PUBLIC_KEY, AlipayConfig.ALI_SIGN_TYPE);
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
        return response;
    }


    /**
     * 支付宝转账
     *
     * @param alipay_user_id 支付宝用户id
     * @param money          转账金额
     * @return
     * @throws AlipayApiException
     */
    public static AlipayFundTransToaccountTransferResponse transfer(String alipay_user_id, String money) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALI_APIURL, AlipayConfig.ALI_APPID, AlipayConfig.ALI_APP_PRIVATE_KEY, AlipayConfig.ALI_FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALI_ALIPAY_PUBLIC_KEY, AlipayConfig.ALI_SIGN_TYPE);
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        request.setBizContent("{" +
                " \"out_biz_no\":\"" + UUIDUtils.getRandomUUID() + "\"," +
                " \"payee_type\":\"ALIPAY_USERID\"," +
                " \"payee_account\":\"" + alipay_user_id + "\"," +
                " \"amount\":\"" + money + "\"," +
                "  \"payer_show_name\":\"素友\"," +
                " \"remark\":\"\"," +
                "  }");
        AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
        return response;
    }
}
